<!DOCTYPE html>
<html>

<head>
  <style>
    form {
      width: 600px;
      margin: 100 auto;
    }

    .notification {
      background: #0A63C4;
      border-radius: 4px;
      padding: 1rem;
      position: fixed;
      top: 1rem;
      right: 1rem;
      color: #fff;
    }

    .show {
      opacity: 1;
      transition: opacity 0.3s ease-in-out;
    }

    .hide {
      opacity: 0;
      transition: opacity 0.3s ease-in-out;
    }
  </style>
  <script src="socket.io.min.js"></script>
</head>

<body>
  <h1>打印设置</h1>
  <form onsubmit="submitForm(event)">
<div>
      <label>URL</label>
      <input type="text" name="url">
    </div>
    <div>
      <label>HTML内容</label><br>
      <textarea name="html" height="500px" width="500px"></textarea>
    </div>
    <div>
      <label>选择打印机</label>
      <select name="printer" id="printer">
        <option>请选择打印机</option>
      </select>
    </div>

    <div>
      <label>是否打印背景</label>
      <input type="checkbox" name="printBackground" checked>
    </div>
    <div>
      <label>是否打印颜色</label>
      <input type="checkbox" name="color" checked>
    </div>

    <div>
      <label>是否静默打印</label>
      <input type="checkbox" name="silent" checked>
    </div>
    <div>
      <label>是否横向打印</label>
      <input type="checkbox" name="landscape">
    </div>
    <div>
      <label>是否排序</label>
      <input type="checkbox" name="collate" checked>
    </div>

    <div>
      <label>打印缩放比例</label>
      <input type="number" name="scaleFactor" value="100">
    </div>
    <div>
      <label>每页页数</label>
      <input type="number" name="pagesPerSheet" value="1">
    </div>

    <div>
      <label>打印份数</label>
      <input type="number" name="copies" value="1">
    </div>
    <div>
      <label>打印页数范围</label>
      <input type="text" name="pageRanges" value="">
    </div>
    <div>
      <label>打印模式</label>
      <select name="duplexMode">
        <option value="simplex">单面</option>
        <option value="shortEdge">双面短边</option>
        <option value="longEdge">双面长边</option>
      </select>
    </div>
    <div>
      <label>打印质量DPI</label>
      <input type="number" name="dpi">
    </div>
    <div>
      <label>页眉</label>
      <input type="text" name="header">
    </div>
    <div>
      <label>页脚</label>
      <input type="text" name="footer">
    </div>
    <div>
        <!--此处可以传入能在浏览器打印纸张里面看到的纸张名称，不同物理打印机的纸张不尽相同-->
      <label>纸张大小</label>
      <select name="pageSize">
        <option value="A4">A4</option>
        <option value="A0">A0</option>
        <option value="A1">A1</option>
        <option value="A2">A2</option>
        <option value="A3">A3</option>
        <option value="A5">A5</option>
        <option value="A6">A6</option>
        <option value="Legal">Legal</option>
        <option value="Letter">Letter</option>
        <option value="Tabloid">Tabloid</option>
      </select>
    </div>
    <button type="submit">打印</button>
  </form>
  <script>
    function submitForm(event) {
      const data = {};
      data.silent = 0;
      data.printBackground = 0;
      data.collate = 0;
      data.color = 0;
      data.landscape = 0;
      data.title="文档打印";
      // data.margins = {
      //   marginType: 'custom',
      //   top: 100,
      //   bottom: 100,
      //   left: 100,
      //   right: 100,
      // };
      data.pageSize = {//这个设置生效的前提是从浏览器能看到自定义纸张设置
        width: 20*1000,//20mm
        height: 40*1000,//40mm
      };

      event.preventDefault() // 阻止表单提交

      const formData = new FormData(event.target)
      for (let [key, value] of formData.entries()) {
        if (key === 'printBackground' || key === 'silent' || key === 'color' || key === 'collate' || key === 'landscape') {
          data[key] = formData.get(key) === 'on' ? 1 : 0
        } else if (key === 'scaleFactor' || key === 'pagesPerSheet' || key === 'copies' || key === 'dpi') {
          data[key] = Number(value)
        } else if (key === 'pageRanges') {
          if (value === "") {
            data[key] = null;
          } else {
            const rangeRegex = /^[0-9]+\-[0-9]+$/

            function isRangeString(str) { //判断输入是否为1-2格式的
              return rangeRegex.test(str)
            }
            if (isRangeString(value)) {
              data[key] = stringToPageRanges(value);
            } else {
              data[key] = null;
            }
          }

        } else {
          data[key] = value;
        }
      }


      if (document.querySelector("#printer").value == "请选择打印机") {
        showMsg('请选择打印机!');
        return;
      } else {
       // data.html = data.html ?? document.body.innerHTML; //此处改成自定义的html
        socket.emit("news", data);
      }
      console.log(data) // 打印结果
    }
    var socket = io.connect('http://localhost:17521');
    if (!socket.connected) {
      showMsg('打印服务器未连接!');
    }
    socket.on("successs", (successs) => {
      showMsg('打印成功!');
    });
    socket.on("error", (error) => {
      console.log(error);
      if (error.msg === "failed") {
        showMsg('打印失败!');
      }
      if (error.msg === "cancelled") {
        showMsg('打印取消!');
      }

    });
    socket.on('connect', function() {
      socket.emit("news", {}); //建立连接，不发送打印内容。
      showMsg('打印机服务器连接成功');
    });
    socket.on('disconnect', function() {
      showMsg('打印服务器失去连接，请检查打印服务器');
    });
    socket.on("printerList", (printers) => {
      printers.forEach(printer => {
        let option = document.createElement("option");
        option.value = printer.name;
        option.innerText = printer.name;
        document.querySelector("#printer").appendChild(option);
      });
    });

    function stringToPageRanges(str) {
      const pageRanges = [];
      const nums = str.split('-');
      const from = Number(nums[0]) - 1;
      if (nums.length > 1) {
        to = Number(nums[1]) - 1;
      }

      pageRanges.push({
        from,
        to
      })
      return pageRanges
    }

    function showMsg(msg) { //消息通知
      const notification = document.createElement('div');
      notification.classList.add('notification', 'show');
      notification.innerText = msg;
      document.body.appendChild(notification);
      setTimeout(() => {
        notification.remove() // 3秒后移除消息元素
      }, 3000);
    }

    /*这里是中文翻译:
    options 对象(可选)
    ◦ silent 布尔值(可选)- 不询问用户打印设置。默认值为`false`。
    ◦ printBackground 布尔值(可选)- 打印网页的背景颜色和图片。默认值为`false`。
    ◦ deviceName 字符串(可选)- 设置要使用的打印机设备名称。必须是系统定义的名称,而不是“用户友好”名称,例如'Brother_QL_820NWB',而不是'Brother QL-820NWB'。
    ◦ color 布尔值(可选)- 设置打印的网页是否是彩色还是灰度。默认值为`true`。
    ◦ margins 对象(可选)
        marginType 字符串(可选)- 可以是`default`、`none`、`printableArea`或`custom`。如果选择`custom`,您还需要指定`top`、`bottom`、`left`和`right`。
        top 数字(可选)- 打印网页的上边距,以像素为单位。
        bottom 数字(可选)- 打印网页的下边距,以像素为单位。
        left 数字(可选)- 打印网页的左边距,以像素为单位。
        right 数字(可选)- 打印网页的右边距,以像素为单位。
    ◦ landscape 布尔值(可选)- 是否将网页打印为横向模式。默认值为`false`。
    ◦ scaleFactor 数字(可选)- 网页的缩放因子。
    ◦ pagesPerSheet 数字(可选)- 每页纸打印的页面数。
    ◦ collate 布尔值(可选)- 是否整理打印的网页。
    ◦ copies 数字(可选)- 要打印的网页副本数。
    ◦ pageRanges 对象[] (可选)- 要打印的页面范围。在macOS上,只信任数组的第一个值。
        from 数字 - 要打印的第一页的索引(以0为基数)。
        to 数字 - 要打印的最后一页的索引(包括在内)(以0为基数)。
    ◦ duplexMode 字符串(可选)- 设置打印网页的双面模式。可以是`simplex`、`shortEdge`或`longEdge`。
    ◦ dpi 记录<string, number>(可选)
        horizontal 数字(可选)- 水平dpi。
        vertical 数字(可选)- 垂直dpi。
    ◦ header 字符串(可选)- 打印为页眉的字符串。
    ◦ footer 字符串(可选)- 打印为页脚的字符串。
    ◦ pageSize 字符串|大小(可选)- 指定打印文档的页面大小。可以是`A0`、`A1`、`A2`、`A3`、`A4`、`A5`、`A6`、`Legal`、`Letter`、`Tabloid`或包含`height`和`width`的对象。
    ◦ callback 函数(可选)
        success 布尔值- 表示打印调用成功。
        failureReason 字符串- 如果打印失败,则回调错误说明。
      当传递自定义的`pageSize`时,Chromium将尝试验证`width_microns`和`height_microns`符合平台指定的最小值。宽度和高度必须至少为353微米,尽管在某些操作系统上可能更高。
      打印网页。当`silent`设置为`true`且`deviceName`为空时,Electron将选择系统的默认打印机和默认设置进行打印。
      使用`page-break-before: always;` CSS样式强制分页。 （已编辑）*/
  </script>
</body>

</html>